home *** CD-ROM | disk | FTP | other *** search
/ Network Supervisor's Toolkit / Network Supervisor's Toolkit.iso / tools / fn_ndi / ndir.prg < prev   
Text File  |  1996-07-10  |  10KB  |  348 lines

  1. /*
  2.  * File......: NDIR.PRG
  3.  * Author....: Mark Mitchelson
  4.  * CIS ID....: 76515,2207
  5.  * Date......: 9/20/94
  6.  * Revision..: $Revision$
  7.  * Log file..: $Logfile$
  8.  *
  9.  * This is an original work by Mark Mitchelson and placed in public domain.
  10.  *
  11.  *
  12.  * Modification history:
  13.  * ---------------------
  14.  *
  15.  * $Log$
  16.  *
  17.  */
  18. #include "fn_nDir.ch"                  //  includes "Directory.ch"
  19. #include "netto.ch"
  20.  
  21.  
  22. //#define FT_TEST
  23. #ifdef FT_TEST
  24.    FUNCTION main
  25.       LOCAL  aDir, iOn, lNovell
  26.  
  27.       //  List all files in F:\SYSTEM
  28.       aDir := fn_nDir("F:\SYSTEM\*.*")
  29.  
  30.       //  Determine if using ndir() or directory() function
  31.       lNovell := ( Len(aDir) > 0 .and. Len(aDir) > F_ATTR )
  32.  
  33.       //  List results
  34.       ? " File    Size" + iif( lNovell, "       Owner         Create Date", "")
  35.       for iOn := 1 to Len( aDir )
  36.          ? Padr( aDir[iOn][F_NAME], 18 ) ;
  37.            + Str( aDir[iOn][F_SIZE], 12 ) + "  " ;
  38.            + Str( iif( lNovell, HILO2L(aDir[iOn][F_OWNER]), "" ), 12 ) + "  " ;
  39.            + iif( lNovell, Dtoc(aDir[iOn][F_CREATE]), "" )
  40.       next
  41.       ?
  42.    RETURN nil
  43. #endif
  44.  
  45.  
  46. /*  $DOC$
  47.  *  $FUNCNAME$
  48.  *     fn_nDir()
  49.  *  $CATEGORY$
  50.  *     File System
  51.  *  $ONELINER$
  52.  *     Mimics Directory() and includes Novell file attributes.
  53.  *
  54.  *  $SYNTAX$
  55.  *     fn_ndir( <cDirSpec> [, <cAttributes> ] ) --> <aDirectory>
  56.  *
  57.  *  $ARGUMENTS$
  58.  *     <cDirSpec>     Drive with path to search for
  59.  *     <cAttributes>  Search for files with the file attributes.
  60.  *                    This is the convention used:
  61.  *                       R - Read Only
  62.  *                       H - Hidden
  63.  *                       S - System
  64.  *                       X - Execute only / Volume label
  65.  *                       D - Directory / Subdirectory bit
  66.  *                       A - Archive
  67.  *                       F - Shareable file
  68.  *
  69.  *  $RETURNS$
  70.  *     <aDirectory> - Empty if nothing found or no rights to that location.
  71.  *
  72.  *                    { { F_NAME, F_SIZE, F_DATE, F_TIME, F_ATTRIB,
  73.  *                        F_OWNER, F_CREATE, F_LASTACCESS }, ... }
  74.  *
  75.  *                   F_DATE is the last update date
  76.  *                   F_TIME is the last update time
  77.  *
  78.  *                   F_ATTRIB ->  "Sh" sharable
  79.  *                                "Sy" system
  80.  *                                "Ro" readonly
  81.  *                                [REST FOLLOW THE VALUS FOR <cAttributes>]
  82.  *
  83.  *     NOTE:  F_OWNER, F_CREATE, F_LASTACCESS are only entered when the
  84.  *            directory is Novell's.
  85.  *
  86.  *  $DESCRIPTION$
  87.  *     This function mimics the Clipper function Directory().  On a
  88.  *     Novell drive it will include the owner #, creation date and the
  89.  *     last access date.
  90.  *
  91.  *     The user must have rights to the directory to view it on Novell.
  92.  *
  93.  *  $EXAMPLES$
  94.  *     fn_ndir("F:\PUBLIC\*.EXE") => { ... }
  95.  *     fn_ndir("*.*", "AH") => { ... }
  96.  *
  97.  *  $SEEALSO$
  98.  *
  99.  *  $INCLUDE$
  100.  *     fn_nDir.ch required if you want the return array indexes named,
  101.  *     i.e. F_NAME, F_OWNER
  102.  *
  103.  *  $END$
  104.  */
  105.  
  106.  
  107. FUNCTION fn_ndir( cDirList, cDirAttrib )
  108.    // Get the drive letter from the directory. (first two characters)
  109.    LOCAL aDirectory := {}
  110.    LOCAL cRequest
  111.    LOCAL cReply
  112.    LOCAL cFileSpec, nAttrSpec
  113.    LOCAL nFileAttrib, cSeq
  114.    LOCAL nDrvHandle, nTemp, cTemp
  115.  
  116.  
  117.    //  Set default values
  118.    cDirList := Upper( cDirList )
  119.    DEFAULT cDirAttrib TO ""
  120.  
  121.  
  122.    //  Determine if Novell or Other Drive
  123.    if At( ":", cDirList ) = 0
  124.       //  No drive included
  125.       nDrvHandle := fn_getdh( fn_DriveNum( ft_Default()))
  126.    else
  127.       nDrvHandle := fn_getdh( fn_DriveNum( cDirList ))
  128.    endif
  129.  
  130.    if nDrvHandle > 0
  131.       //  Novell Network Directory
  132.       //--------------------------
  133.  
  134.       //  Define <cFileSpec>
  135.       if At( ":", cDirList ) = 0
  136.          //  i.e.  public\*.*, *.*
  137.          cFileSpec := fn_DVolName( ft_Default() ) + ":\" ;
  138.                     + iif( Empty(cDirList), "*.*", cDirList )
  139.  
  140.       else
  141.          //  i.e.  f:\public, f:*.*
  142.          cFileSpec := fn_DVolName( Left(cDirList,1)) + ":"
  143.          cDirList := Substr( cDirList, At( ":", cDirList )+1 )
  144.          cFileSpec += iif( Left( cDirList, 1 ) = "\", "", "\") + cDirList
  145.       endif
  146.  
  147.       //  Define <nAttrSpec>
  148.       nAttrSpec := 0
  149.       iif( cDirAttrib $ "R", nAttrSpec := fn_setbit( nAttrSpec, 0 ), )
  150.       iif( cDirAttrib $ "H", nAttrSpec := fn_setbit( nAttrSpec, 1 ), )
  151.       iif( cDirAttrib $ "S", nAttrSpec := fn_setbit( nAttrSpec, 2 ), )
  152.       iif( cDirAttrib $ "X", nAttrSpec := fn_setbit( nAttrSpec, 3 ), )
  153.       iif( cDirAttrib $ "D", nAttrSpec := fn_setbit( nAttrSpec, 4 ), )
  154.       iif( cDirAttrib $ "A", nAttrSpec := fn_setbit( nAttrSpec, 5 ), )
  155.       iif( cDirAttrib $ "F", nAttrSpec := fn_setbit( nAttrSpec, 7 ), ) // "Sh"
  156.  
  157.       //  Loop through all in directory
  158.       //-------------------------------
  159.       cSeq := I2Bin( -1 )                    //  Start up the search
  160.       do while .T.
  161.  
  162.          //  Build Request
  163.          cRequest := I2BYTE( 15 ) ;          // Subservice 0Fh
  164.                    + cSeq ;                  // FFFFh - start sequence
  165.                    + I2BYTE( 0 ) ;           // Dir handle (OPTIONAL)
  166.                    + I2BYTE( nAttrSpec ) ;   // Novell search attrib bits
  167.                    + I2BYTE( Len(cFileSpec)) ;// Len of file spec
  168.                    + Upper(cFileSpec)
  169.          cReply := Replicate( chr(0), 94 )
  170.  
  171.          //  Transaction
  172.          if _fnReq( 227, cRequest, @cReply ) == ESUCCESS    // E3h
  173.  
  174.             //  Process Reply
  175.             //---------------
  176.             aadd( aDirectory, Array( 8 ))
  177.             cSeq := Substr( cReply, 0, 2 )
  178.             aTail(aDirectory)[F_NAME] := fn_NoNull( Substr( cReply, 3, 14 ))
  179.             nTemp := Asc( Substr( cReply, 17, 1 ))
  180.             aTail(aDirectory)[F_ATTR] := iif( fn_isbit(nTemp,0), "Ro", "") ; // ReadOnly
  181.                                        + iif( fn_isbit(nTemp,1), "H", "") ; // Hidden
  182.                                        + iif( fn_isbit(nTemp,2), "Sy", ""); // System
  183.                                        + iif( fn_isbit(nTemp,3), "X", "") ; // Execute-Only
  184.                                        + iif( fn_isbit(nTemp,4), "D", "") ; // Directory
  185.                                        + iif( fn_isbit(nTemp,5), "A", "") ; // Archive
  186.                                        + iif( fn_isbit(nTemp,7), "Sh", "")  // Share
  187.  
  188.             aTail(aDirectory)[F_SIZE] := HILO2L( Substr( cReply, 19, 4 )) // Size
  189.             aTail(aDirectory)[F_DATE] := fn_W2Date( Substr( cReply, 27, 2 ))  // Last Change Date
  190.             aTail(aDirectory)[F_TIME] := fn_W2Time( Substr( cReply, 29, 2 ))  // Last Change Time
  191.             aTail(aDirectory)[F_OWNER] := Id2Owner( Substr( cReply, 31, 4 ))     // Owner
  192. *            aTail(aDirectory)[F_CREATE] := fn_W2Date( Substr( cReply, 23, 2 ))  // Create
  193. *            aTail(aDirectory)[F_LASTACCESS] := fn_W2Date( Substr( cReply, 25, 2 ))  // Last Access
  194.          else
  195.  
  196.             EXIT
  197.          endif
  198.       enddo
  199.    else
  200.  
  201.       //  LOCAL or Non Novell Drive
  202.       aDirectory := Directory( cDirList, cDirAttrib )
  203.    endif
  204. RETURN(aDirectory)
  205.  
  206.  
  207.  
  208. /*  $DOC$
  209.  *  $FUNCNAME$
  210.  *     fn_DriveNum()
  211.  *  $CATEGORY$
  212.  *     Miscellanious
  213.  *
  214.  *  $ONELINER$
  215.  *     Convert a drive letter to its DOS numeric
  216.  *
  217.  *  $SYNTAX$
  218.  *     fn_ndir( [<cDrive> | <cDriveWithPath> ] ) -> integer
  219.  *
  220.  *  $ARGUMENTS$
  221.  *
  222.  *  $RETURNS$
  223.  *     Array
  224.  *
  225.  *  $DESCRIPTION$
  226.  *
  227.  *  $EXAMPLES$
  228.  *     fn_DriveNum("C") -> 3
  229.  *     fn_DriveNum("F:\PUBLIC") -> 5
  230.  *
  231.  *  $SEEALSO$
  232.  *
  233.  *  $INCLUDE$
  234.  *     netto.ch
  235.  *  $END$
  236.  */
  237. FUNCTION  fn_DriveNum( cDrive )
  238.    //  Convert a drive letter to its number A=0,..F=5,...
  239. RETURN( Asc(Upper(Left(cDrive,1))) - Asc('A') )
  240.  
  241.  
  242.  
  243. /*  $DOC$
  244.  *  $FUNCNAME$
  245.  *     fn_W2Date()
  246.  *  $CATEGORY$
  247.  *     Miscellanious
  248.  *  $ONELINER$
  249.  *     Convert a dos binary date to its Clipper equivalant.
  250.  *
  251.  *  $SYNTAX$
  252.  *     fn_W2Date( <cWord> ) -> date
  253.  *
  254.  *  $ARGUMENTS$
  255.  *
  256.  *  $RETURNS$
  257.  *     Date, Invalid date on error
  258.  *
  259.  *  $DESCRIPTION$
  260.  *     This converts a 2 character representation of a binary word to a
  261.  *     Clipper date.
  262.  *
  263.  *       Byte1           Byte 2
  264.  *       7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
  265.  *       |   Year     | Month |   Day  |
  266.  *
  267.  *
  268.  *  $EXAMPLES$
  269.  *
  270.  *  $SEEALSO$
  271.  *
  272.  *  $INCLUDE$
  273.  *     netto.ch
  274.  *  $END$
  275.  */
  276. FUNCTION  fn_W2Date( cWord )
  277.    //  Convert the 2 byte word to a data
  278.    LOCAL nYear, nMonth, nDay, cTemp
  279.  
  280.    //  Bytes 15-9
  281.    cTemp := fn_ror( " "+Left( cWord, 1 ), 1 )
  282.    nYear := 80 + Asc( Substr( cTemp, 2, 1 ))
  283.    //  Bytes 8-5
  284.    cTemp := fn_ror( cWord, 5 )
  285.    nMonth := fn_And( Asc( Substr( cTemp, 2, 1 )), 15 )
  286.    //  Bytes 4-0
  287.    nDay := fn_And( Asc( Substr( cWord, 2, 1 )), 31 )
  288. RETURN( Ctod( Str(nMonth,2)+"/"+Str(nDay,2)+"/"+Str(nYear,2) ))
  289.  
  290.  
  291.  
  292. /*  $DOC$
  293.  *  $FUNCNAME$
  294.  *     fn_W2Time()
  295.  *  $CATEGORY$
  296.  *     Miscellanious
  297.  *  $ONELINER$
  298.  *     Convert a dos binary time to its Clipper equivalant.
  299.  *
  300.  *  $SYNTAX$
  301.  *     fn_W2Time( <cWord> ) -> time
  302.  *
  303.  *  $ARGUMENTS$
  304.  *
  305.  *  $RETURNS$
  306.  *     Time - "XX:XX:XX"
  307.  *
  308.  *  $DESCRIPTION$
  309.  *     This converts a 2 character representation of a binary word to a
  310.  *     Clipper time.
  311.  *
  312.  *       Byte1           Byte 2
  313.  *       7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
  314.  *       |  Time  |   Minute  | Second |
  315.  *
  316.  *
  317.  *  $EXAMPLES$
  318.  *
  319.  *  $SEEALSO$
  320.  *
  321.  *  $INCLUDE$
  322.  *     netto.ch
  323.  *  $END$
  324.  */
  325. FUNCTION  fn_W2Time( cWord )
  326.    //  Convert the 2 byte word to a time
  327.    LOCAL cTemp
  328.    LOCAL nHour, nMin, nSec
  329.  
  330.    //  Bytes 15-11
  331.    cTemp := fn_ror( " "+Left( cWord, 1 ), 3 )
  332.    nHour := Asc( Substr( cTemp, 2, 1 ))
  333.    //  Bytes 10-5
  334.    cTemp := fn_ror( cWord, 5 )
  335.    nMin := fn_And( Asc( Substr( cTemp, 2, 1 )), 63 )
  336.    //  Bytes 4-0
  337.    nSec := fn_And( Asc( Substr( cWord, 1, 2 )), 31 )
  338. RETURN( lTrim(Str(nHour))+":"+lTrim(Str(nMIn))+":"+lTrim(Str(nSec)) )
  339.  
  340.  
  341. STATIC FUNCTION Id2Owner( cDWord )
  342.    // Convert a Double Word Owner ID to a name
  343.    LOCAL cTemp, nType := OT_USER
  344.  
  345.    cTemp := FN_BndONam( HILO2L(cDWord), @nType )
  346. RETURN( cTemp )
  347. //  end
  348.